package m.jclecai.com.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.facebook.rebound.SimpleSpringListener;
import com.facebook.rebound.Spring;
import com.facebook.rebound.SpringChain;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import m.jclecai.com.R;
import m.jclecai.com.utils.BaseUtils;
import m.jclecai.com.view.common.BallView;

/**
 * Created by zed on 2018/3/22.
 * 仅用于选择号码球的动画
 */

public class NumberLotteryEffectView extends RelativeLayout {
    //动画连锁效果
    private SpringChain springChain;
    private List<View> mEffectView;       //显示屏幕中间的小球
    private List<View> mTargetEffectView;
    private int recordSpringChainEnd = 0;
    private int recordMoveAnimationCoung = 0;
    private List<String> balls;
    private boolean isStartEffect = false;
    private int moveDistance = 30;
    private BALL currMode = BALL.RED;
    private AbsListView[] absListViews;
    private RecyclerView[] layoutManagers;
    private int[] mTargetEffectViewTop;
    private Map<Integer, BALL> ballCorlor;
    private boolean fromZore = true;
    private int screenWidth = 0;
    private int screenHeight = 0;
    private int generateViewId = 0;
    //容器的间隔
    private int containerMargin = 10;
    //小球间的间隔
    private int split = 10;

    public enum BALL {
        RED, BLUE
    }

    private NumberLotteryEffectView(@NonNull Context context) {
        super(context);
        init();
    }

    private NumberLotteryEffectView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private NumberLotteryEffectView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setGravity(Gravity.CENTER);
        generateViewId = BaseUtils.generateViewId();
//        setPadding(containerMargin, 0, containerMargin, 0);
        screenWidth = getResources().getDisplayMetrics().widthPixels;
        screenHeight = getResources().getDisplayMetrics().heightPixels;
        ballCorlor = new HashMap<>();
        balls = new ArrayList<>();
        mEffectView = new ArrayList<>();
        mTargetEffectView = new ArrayList<>();
        setClickable(true);
    }

    /**
     * @param weiBall     小球
     * @param recycleview 小球所在的容器 recycleview
     */
    private void setTargetEffectView(List<String> weiBall, View recycleview, int vIndex) {
        if (!isStartEffect) {
            for (int j = 0; j < weiBall.size(); j++) {
                int bIndex = Integer.valueOf(weiBall.get(j)) - 1;
                if (fromZore) bIndex += 1;

                if (recycleview instanceof ViewGroup) {
                    ViewGroup vg = (ViewGroup) recycleview;
                    //这里遍历是为了以后嵌套的不管是recycleview 还是 AbsListView都可以执行下面的逻辑
                    for (int k = 0; k < vg.getChildCount(); k++) {
                        View childAt = vg.getChildAt(k);
                        if (childAt instanceof RecyclerView || childAt instanceof AbsListView) {
                            //ballView的父容器
                            View bp = ((ViewGroup) childAt).getChildAt(bIndex);
                            View ballView = bp.findViewById(R.id.bv_ball_view);
                            if (mTargetEffectViewTop != null)
                                mTargetEffectViewTop[vIndex] = recycleview.getTop() + bp.getTop() + recycleview.getHeight();
//                            Log.e("targetView", weiBall.get(j) + ";parent-" + recycleview.getTop() + ";vg-" + bp.getTop() + "-" + bp.getHeight() + ";ballView" + ballView.getHeight() + "-" + ballView.getTop());
                            if (ballView != null && ballView instanceof BallView)
                                balls.add(((BallView) ballView).getNumber());
                            else
                                balls.add(weiBall.get(j));
                            if (ballView == null) continue;
                            setTargetEffectView(ballView);
                        }
                    }
                }
            }
        }
    }

    /**
     * @param weiBall       根据小球寻找对应下标的targetView
     * @param layoutManager 綁定小球的
     *                      recycleview
     *                      **********\--LinearLayout->\textview
     *                      ***************************\recycleview
     *                      **************************************\--LinearLayout->\...其他view
     *                      *******************************************************\BallView
     *                      <p>
     *                      当前逻辑的数字彩嵌套形式为recycleview 套 recycleview
     *                      嵌套的recycleview 则为小球 BallView所在的容器
     */
    private void setTargetEffectView(final List<String> weiBall, RecyclerView layoutManager) {
        if (!isStartEffect)
            if (layoutManager.getChildCount() == 1) {
                setTargetEffectView(weiBall, layoutManager.getChildAt(0), 0);
            } else {
                mTargetEffectViewTop = new int[weiBall.size()];
                for (int i = 0; i < mTargetEffectViewTop.length; i++) {
                    final String s = weiBall.get(i);
                    View childAt = layoutManager.getChildAt(i);
                    setTargetEffectView(new ArrayList<String>() {{
                        add(s);
                    }}, childAt, i);
                }
            }

//            for (int i = 0; i < layoutManager.getChildCount(); i++) {
//                if (itemCount > 1) {
//
//                    new ArrayList<String>() {{
//                        weiBall.get(i);
//                    }};
//                    setTargetEffectView(, layoutManager.getChildAt(i));
//                } else {
//                    setTargetEffectView(weiBall, layoutManager.getChildAt(i));
//                }

//                View viewByPosition = layoutManager.getChildAt(i);
//                for (int j = 0; j < weiBall.size(); j++) {
//                    int index = Integer.valueOf(weiBall.get(j)) - 1;
//                    if (fromZore) index += 1;
//
//                    if (viewByPosition instanceof ViewGroup) {
//                        ViewGroup vg = (ViewGroup) viewByPosition;
//                        for (int k = 0; k < vg.getChildCount(); k++) {
//                            View childAt = vg.getChildAt(k);
//                            if (childAt instanceof RecyclerView || childAt instanceof AbsListView) {
//                                View ballView = ((ViewGroup) childAt).getChildAt(index).findViewById(R.id.bv_ball_view);
//                                if (ballView != null && ballView instanceof BallView)
//                                    balls.add(((BallView) ballView).getNumber());
//                                else
//                                    balls.add(weiBall.get(j));
//                                if (ballView == null) continue;
//                                setTargetEffectView(ballView);
//                            }
//                        }
//                    }
//                }
//            }
    }

    /**
     * @param weiBall       根据小球寻找对应下标的targetView
     * @param layoutManager 綁定小球的
     */
    private void setTargetEffectView(List<String> weiBall, AbsListView layoutManager) {
        balls.addAll(weiBall);
        if (!isStartEffect)
            for (int i = 0; i < balls.size(); i++) {
                int index = Integer.valueOf(balls.get(i)) - 1;
                if (fromZore) index += 1;
                View viewByPosition = layoutManager.getChildAt(index);
                viewByPosition.setTag(R.id.number_lottery_target_index, index);
                setTargetEffectView(viewByPosition);
            }
    }


    /**
     * @param layoutManager 綁定小球的位置
     */
    private void setTargetEffectView(AbsListView... layoutManager) {
        absListViews = layoutManager;
        if (!isStartEffect) {
            int colorIndex = 0;
            for (int i = 0; i < layoutManager.length; i++) {
                AbsListView absListView = layoutManager[i];
                if (absListView.getVisibility() == GONE) continue;
                Object tag = absListView.getTag(R.id.number_lottery_target_data_index);
                if (tag == null) continue;
                List<String> weiBall = (List<String>) tag;
                BALL ball = (BALL) absListView.getTag(R.id.number_lottery_target_ball_color);
                for (int j = 0; j < weiBall.size(); j++) {
                    int index = Integer.valueOf(weiBall.get(j)) - 1;
                    if (fromZore) index += 1;
                    View viewByPosition = absListView.getChildAt(index);
                    if (viewByPosition == null) continue;
                    View ballView = viewByPosition.findViewById(R.id.bv_ball_view);
                    if (ballView != null && ballView instanceof BallView)
                        balls.add(((BallView) ballView).getNumber());
                    else
                        balls.add(weiBall.get(j));
                    viewByPosition.setTag(R.id.number_lottery_target_index, index);
                    setTargetEffectView(viewByPosition);
//                    Log.e("setColor", colorIndex + "" + ball.name());
                    ballCorlor.put(colorIndex, ball);
                    colorIndex++;
                }
            }

        }
    }

    /**
     * @param layoutManager 綁定小球的位置
     */
    private void setTargetEffectView(RecyclerView... layoutManager) {
        layoutManagers = layoutManager;
        if (!isStartEffect) {
            int colorIndex = 0;
            for (int i = 0; i < layoutManager.length; i++) {
                RecyclerView rv = layoutManager[i];
                Object tag = rv.getTag(R.id.number_lottery_target_data_index);
                if (tag == null) continue;
                List<String> weiBall = (List<String>) tag;
                BALL ball = (BALL) rv.getTag(R.id.number_lottery_target_ball_color);
                for (int j = 0; j < weiBall.size(); j++) {
                    int index = Integer.valueOf(weiBall.get(j)) - 1;
                    if (fromZore) index += 1;
                    View viewByPosition = rv.getChildAt(index);
                    if (viewByPosition == null) continue;
                    View ballView = viewByPosition.findViewById(R.id.bv_ball_view);
                    if (ballView != null && ballView instanceof BallView)
                        balls.add(((BallView) ballView).getNumber());
                    else
                        balls.add(weiBall.get(j));
                    viewByPosition.setTag(R.id.number_lottery_target_index, index);
                    setTargetEffectView(viewByPosition);
                    ballCorlor.put(colorIndex, ball);
                    colorIndex++;
                }
            }

        }
    }

    /**
     * 从左到右依次，设置球最终移动到的位置
     *
     * @param targetEffectView
     */
    private void setTargetEffectView(List<View> targetEffectView) {
        if (!isStartEffect)
            this.mTargetEffectView.addAll(targetEffectView);
    }

    /**
     * 从左到右依次，设置球最终移动到的位置
     *
     * @param targetEffectView
     */
    private void setTargetEffectView(View targetEffectView) {
        if (!isStartEffect)
            this.mTargetEffectView.add(targetEffectView);
    }

    public void startEffect() {
        startEffect(null);
    }

    /**
     * 开始动画效果
     *
     * @param mViewListener 自定view的样式
     */
    protected void startEffect(OnViewListener mViewListener) {
        if (isStartEffect) return;
        isStartEffect = true;
        recordSpringChainEnd = 0;
        springChain = SpringChain.create(40, 6, 50, 7);
        for (int i = 0; i < balls.size(); i++) {
            //如果不想要固定的view可以在实现回掉
            View createView = mViewListener == null ? null : mViewListener.createView();
            final View ball = createView == null ? createBall(balls.get(i), ballCorlor.get(i)) : createView;
            ball.setVisibility(INVISIBLE);
            addView(ball);
            adjustCacluViewPosition(ball, i);
            mEffectView.add(ball);
            springChain.addSpring(new SimpleSpringListener() {
                @Override
                public void onSpringUpdate(Spring spring) {
                    super.onSpringUpdate(spring);
                    ball.setScaleX((float) spring.getCurrentValue() / moveDistance);
                    ball.setScaleY((float) spring.getCurrentValue() / moveDistance);
                    ball.setRotation((float) spring.getCurrentValue() / moveDistance);
                    ball.setTranslationX(moveDistance - (float) spring.getCurrentValue());
                }

                @Override
                public void onSpringActivate(Spring spring) {
                    super.onSpringActivate(spring);
                    ball.setVisibility(VISIBLE);
                }

                @Override
                public void onSpringAtRest(Spring spring) {
                    super.onSpringAtRest(spring);
                    recordSpringChainEnd++;
                    if (recordSpringChainEnd == balls.size()) {
                        start();
                    }
                }
            });
        }
        List<Spring> springs = springChain.getAllSprings();
        for (int i = 0; i < springs.size(); i++) {
            springs.get(i).setCurrentValue(0);
        }
        if (springs.size() > 0)
            springChain.setControlSpringIndex(0).getControlSpring().setEndValue(moveDistance);
    }

    /**
     * 创建不同效果的小球
     *
     * @param txt
     * @return
     */
    private View createBall(String txt, BALL mode) {
        mode = mode == null ? currMode : mode;
        final View inflate = LayoutInflater.from(getContext()).inflate(R.layout.view_number_effect_ball, this, false);

        TextView tvBall = (TextView) inflate;
        tvBall.setTextColor(Color.parseColor("#ffffff"));
        switch (mode) {
            case RED:
                tvBall.setBackgroundResource(R.drawable.red_ball);
                break;
            case BLUE:
                tvBall.setBackgroundResource(R.drawable.blue_ball);
                break;
        }
        tvBall.setText(txt);
        return inflate;
    }

    /**
     * 暂时写死 后期需要根据屏幕来适配
     * @param inflate
     * @param index
     */
    private void adjustCacluViewPosition(View inflate, int index) {
        //小球间的总间隔
//        int allSplit = (balls.size() - 1) * split;
        //每个小球的宽度
//        int width = (screenWidth - allSplit - containerMargin * 2) / balls.size();
        inflate.setId(generateViewId + index);
        if (index > 0) {
            LayoutParams layoutParams = (LayoutParams) inflate.getLayoutParams();
            if(index <7){
                layoutParams.addRule(RIGHT_OF, generateViewId + (index - 1));
            }else if(index == 7){
                layoutParams.addRule(BELOW, generateViewId + (index - 1));
            }else {
                layoutParams.addRule(RIGHT_OF, generateViewId + (index - 1));
                layoutParams.addRule(BELOW, generateViewId + (7 - 1));
            }
        }
        //球过多超出屏幕 需要计算小球位置
//        inflate.setLayoutParams(new LayoutParams(width, width));

    }


    public List<View> getTargetEffectView() {
        return mTargetEffectView;
    }

    private void start() {
        for (int i = 0; i < mTargetEffectView.size(); i++) {
            Rect rect = new Rect();
            mTargetEffectView.get(i).getGlobalVisibleRect(rect);
            dispearAnimation(i, rect);
        }
    }

    private void dispearAnimation(int index, Rect targetEffectViewRect) {
        View effectView = mEffectView.get(index);
        AnimatorSet animatorSet = new AnimatorSet();
        ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(effectView, "ScaleX", 1, 1);
        ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(effectView, "ScaleY", 1, 1);

        int tevX = targetEffectViewRect.left + targetEffectViewRect.width() / 2;
        int tevY = targetEffectViewRect.top + targetEffectViewRect.height() / 2;
        if (mTargetEffectViewTop != null) {
            tevY += mTargetEffectViewTop[index] - targetEffectViewRect.top;
        }
        Rect effectViewRect = new Rect();
        effectView.getGlobalVisibleRect(effectViewRect);

        int evX = effectViewRect.left + effectView.getWidth() / 2;
        int evY = effectViewRect.top + effectView.getHeight() / 2;
        int dx = tevX - evX;
        int dy = tevY - evY;
        //这里的话，我们是需要计算这个牌到这个具体位置的dx和dy
        ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(effectView, "translationX", 0, dx);
        ObjectAnimator objectAnimator4 = ObjectAnimator.ofFloat(effectView, "translationY", 0, dy);
        animatorSet.playTogether(objectAnimator1, objectAnimator2, objectAnimator3, objectAnimator4);
        animatorSet.setDuration(500);
        animatorSet.start();

        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                recordMoveAnimationCoung++;
                if (recordMoveAnimationCoung == mEffectView.size()) {
                    if (mOnAnimatorListnener != null) {
                        mOnAnimatorListnener.onAnimatorEnd(mTargetEffectView);
                    }
                    if (mOnAnimatorListneners != null) {
                        mOnAnimatorListneners.onAnimatorEnd(absListViews);
                    }
                    if (mOnRecycleListneners != null) {
                        mOnRecycleListneners.onAnimatorEnd(layoutManagers);
                    }
                    removeAllViews();
                    isStartEffect = false;
                    recordMoveAnimationCoung = 0;
                    mEffectView.clear();
                    mTargetEffectView.clear();
                    ballCorlor.clear();
                    absListViews = null;
                    layoutManagers = null;
                    balls.clear();
                    ((ViewGroup) ((Activity) getContext()).findViewById(android.R.id.content)).removeView(NumberLotteryEffectView.this);
                }
            }
        });
    }

    /**
     * 对View的一个宽高测量；
     *
     * @param view
     * @return
     */
    public int getMeasureHeight(View view) {
        int measureSpec = MeasureSpec.makeMeasureSpec((1 << 30) - 1, MeasureSpec.AT_MOST);
        view.measure(measureSpec, measureSpec);
        return view.getMeasuredHeight();
    }

    private void resetAnimation() {
        //这里这里对其poker进行一个还原；
        for (View centerPoker : mEffectView) {
            centerPoker.setTranslationY(0);
            centerPoker.setTranslationX(0);
            centerPoker.setRotationY(0);
//            centerPoker.findViewById(R.id.ep_poker).setVisibility(View.INVISIBLE);
//            centerPoker.findViewById(R.id.iv_img).setVisibility(View.VISIBLE);
            centerPoker.setScaleY(1);
            centerPoker.setScaleX(1);
        }
    }


    protected OnAnimatorListnener mOnAnimatorListnener;
    protected OnAnimatorListneners mOnAnimatorListneners;
    protected OnRecycleListneners mOnRecycleListneners;
    protected OnViewListener mViewListener;

    private void setOnAnimatorListnener(OnAnimatorListnener onAnimatorListnener) {
        mOnAnimatorListnener = onAnimatorListnener;
    }

    private void setOnAnimatorListneners(OnAnimatorListneners onAnimatorListneners) {
        mOnAnimatorListneners = onAnimatorListneners;
    }

    public interface OnRecycleListneners {
        void onAnimatorEnd(RecyclerView... mTargetEffectView);
    }

    public interface OnViewListener {
        View createView();
    }

    public interface OnAnimatorListnener {
        void onAnimatorEnd(List<View> mTargetEffectView);
    }

    public interface OnAnimatorListneners {
        void onAnimatorEnd(AbsListView... absListViews);
    }

    public static class Builder {
        static NumberLotteryEffectView numberLotteryEffectView;
        static Context context;

        public static Builder create(Context mContent) {
            context = mContent;
            numberLotteryEffectView = new NumberLotteryEffectView(context);
            return new Builder();
        }

        public Builder setOnAnimatorListnener(OnAnimatorListnener onAnimatorListnener) {
            numberLotteryEffectView.setOnAnimatorListnener(onAnimatorListnener);
            return this;
        }

        public Builder setOnAnimatorListneners(OnAnimatorListneners onAnimatorListnener) {
            numberLotteryEffectView.setOnAnimatorListneners(onAnimatorListnener);
            return this;
        }

        public Builder setOnRecycleListneners(OnRecycleListneners onAnimatorListnener) {
            numberLotteryEffectView.setOnRecycleListneners(onAnimatorListnener);
            return this;
        }

        public Builder setTargetEffectView(List<String> weiBall, RecyclerView layoutManager) {

            return this;
        }

        public Builder setTargetEffectView(List<String> weiBall, RecyclerView layoutManager, int itemCount) {
            numberLotteryEffectView.setTargetEffectView(weiBall, layoutManager);
            return this;
        }

        public Builder setTargetEffectView(AbsListView... layoutManager) {
            numberLotteryEffectView.setTargetEffectView(layoutManager);
            return this;
        }

        public Builder setTargetEffectView(RecyclerView... layoutManager) {
            numberLotteryEffectView.setTargetEffectView(layoutManager);
            return this;
        }

        public Builder setCurrMode(BALL currMode) {
            numberLotteryEffectView.setCurrMode(currMode);
            return this;
        }

        /**
         * 这个参数需要设置在create之后
         *
         * @param bool
         * @return
         */
        public Builder fromZero(boolean bool) {
            numberLotteryEffectView.fromZero(bool);
            return this;
        }


        public Builder setTargetEffectView(List<String> weiBall, AbsListView layoutManager) {
            numberLotteryEffectView.setTargetEffectView(weiBall, layoutManager);
            return this;
        }

        public NumberLotteryEffectView build() {
            return numberLotteryEffectView;
        }

    }

    public void fromZero(boolean fromZore) {
        this.fromZore = fromZore;
    }

    public void setCurrMode(BALL currMode) {
        this.currMode = currMode;
    }

    public NumberLotteryEffectView attachToWindow() {
        ((ViewGroup) ((Activity) getContext()).findViewById(android.R.id.content)).addView(this);
        return this;
    }

    public void setOnRecycleListneners(OnRecycleListneners mOnRecycleListneners) {
        this.mOnRecycleListneners = mOnRecycleListneners;
    }
}
